home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2003 November A / PCWK1103A.iso / ABBYY FineReader 7.0 PRO / data1.cab / gs_cidfn.ps < prev    next >
Text File  |  2002-04-04  |  22KB  |  702 lines

  1. %    Copyright (C) 1995, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: gs_cidfn.ps,v 1.18.4.5 2002/04/03 07:31:14 mpsuzuki Exp $
  14. % ProcSet for implementing CIDFont and CIDMap resources.
  15. % When this is run, systemdict is still writable.
  16.  
  17. % ---------------- Defining CIDFont resources ---------------- %
  18.  
  19. % Define a CIDFont resource.  This is the defineresource implementation for
  20. % the CIDFont resource category.
  21.  
  22. /.checkfonttype {    % <cidfont> <fonttype> .checkfonttype <cidfont> <new?>
  23.   1 index /FID known {
  24.     1 index /FontType get ne {
  25.       /definefont cvx /invalidfont signalerror
  26.     } if false
  27.   } {
  28.     1 index /FontType 3 -1 roll put true
  29.   } ifelse
  30. } bind def
  31.  
  32. /.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse
  33. .cidfonttypes
  34.  
  35. 30 dict begin
  36.  
  37. % The key in .cidfonttypes is the CIDFontType value;
  38. % the value is a procedure that takes a font name and the CIDFont dictionary
  39. % and replaces the latter with a real font.
  40.  
  41. % ------ CIDFontType 0 (FontType 9) ------ %
  42.  
  43. % We add the following entries to the CIDFont dictionary, in addition to
  44. % the ones documented by Adobe:
  45. %    SubrCache - dictionary for caching Subr arrays
  46. % For CIDFonts where we read the data from disk incrementally:
  47. %    GlyphData is 0 (arbitrary)
  48. %    DataSource - a ReusableStreamDecode filter for the data
  49. % We also add a FID entry, and possibly a Subrs entry, to each element of
  50. % FDArray.
  51.  
  52. dup 0 {
  53.   9 .checkfonttype {
  54.     /CIDInit /ProcSet findresource begin
  55.     .completefont9
  56.     end
  57.   } if
  58.   1 index exch .buildfont9 exch pop
  59. } bind put
  60.  
  61. % Add entries to a new CIDFontType 0 font per documentation (FontMatrix)
  62. % or for .buildfont9 (FDArray.Private.Subrs).
  63. /.completefont9 {    % <cidfont0> .completefont9 <cidfont0>
  64.   currentglobal 3 1 roll dup gcheck setglobal
  65.   dup /FontMatrix known not {
  66.     dup /FontMatrix [0.001 0 0 0.001 0 0] put
  67.     dup /FDArray get {
  68.       /FontMatrix get [1000 0 0 1000 0 0] 1 index concatmatrix pop
  69.     } forall
  70.   } if
  71.   dup /FDArray get {
  72.         % Read the Subrs if necessary.
  73.     dup /Private get dup /Subrs known not {
  74.       dup /SubrCount .knownget {
  75.         % Stack: font Private SubrCount
  76.     currentglobal 3 1 roll 1 index gcheck setglobal
  77.     array 1 index /Subrs 3 -1 roll put
  78.         % Stack: font global Private
  79.     2 index begin begin .loadsubrs end end
  80.     setglobal
  81.       } {
  82.     pop
  83.       } ifelse readonly pop
  84.     } {
  85.       pop pop
  86.     } ifelse
  87.   } forall
  88.   3 -1 roll setglobal
  89. } bind def
  90.  
  91. % Read some Subrs for the current Type 1 subfont.
  92. % The subfont's Private dict is currentdict; the CIDFont itself is the
  93. % next dictionary on the stack.
  94. /.readsubrs {        % <Subrs> <start> .readsubrs <Subrs>
  95.   1 SubrCount 1 sub {
  96.     dup SDBytes mul SubrMapOffset add
  97.     dup SDBytes .readint exch SDBytes add SDBytes .readint
  98.     1 index sub string ReadString 2 index 3 1 roll put
  99.   } for
  100. } bind def
  101.  
  102. % Ensure that all the Subrs for the current Type 1 subfont are loaded.
  103. % The subfont's Private dict is currentdict; the CIDFont itself is the
  104. % next dictionary on the stack.
  105. /.loadsubrs {
  106.   Subrs length 0 ne {
  107.     SubrCache SubrMapOffset .knownget {
  108.         % We've already loaded some Subrs at this offset.
  109.         % Make sure we've got as many as we need.
  110.       dup length SubrCount lt {
  111.         % We need to load more.
  112.     SubrCount array exch 1 index copy length .readsubrs
  113.     SubrCache SubrMapOffset 2 index put
  114.       } if
  115.     } {
  116.         % We haven't loaded any Subrs at this offset yet.
  117.       SubrCount array 0 .readsubrs
  118.       SubrCache SubrMapOffset 2 index put
  119.     } ifelse
  120.     Subrs copy pop
  121.   } if
  122. } bind def
  123.  
  124. % ------ CIDFontType 1 (FontType 10) ------ %
  125.  
  126. dup 1 {
  127.   10 .checkfonttype pop
  128.   1 index exch .buildfont10 exch pop
  129. } bind put
  130.  
  131. % ------ CIDFontType 2 (FontType 11) ------ %
  132.  
  133. dup 2 {
  134.   11 .checkfonttype pop
  135.   1 index exch .buildfont11 exch pop
  136. } bind put
  137.  
  138. pop        % .cidfonttypes
  139.  
  140. % ---------------- Reading CIDFontType 0 files ---------------- %
  141.  
  142. /StartData {        % <(Binary)|(Hex)> <datalength> StartData -
  143.             %   (currentdict is CID font dict)
  144.         % If we're loading a resource file and the data format is
  145.         % binary, we can just save a pointer to the data and load it
  146.         % incrementally.
  147.   mark {
  148.         % Previous versions of this code made provisions for
  149.         % reading hex-encoded data incrementally.  Since hex data
  150.         % doesn't seem to be used in practice, we no longer bother.
  151.     2 index (Binary) ne { stop } if
  152.     currentfile .currentresourcefile ne { stop } if
  153.         % Hack: the pdfwrite driver relies on finalization to write
  154.         % out fonts.  However, the font may be finalized after the
  155.         % resource file, in which case the resource file will be
  156.         % closed.  So if the current output device is pdfwrite,
  157.         % don't use incremental loading.
  158.     currentdevice .devicename /pdfwrite eq { stop } if
  159.     currentfile fileposition
  160.   } .internalstopped {
  161.         % File is not positionable, or uses hex data.
  162.         % Load the data now.
  163.     cleartomark exch (Hex) eq
  164.       { { currentfile exch readhexstring pop } }
  165.       { { currentfile exch readstring pop } }
  166.     ifelse exch
  167.         % Stack: readproc length
  168.     dup 65400 le {
  169.         % readstring with a 0-length string causes a rangecheck,
  170.         % but a data length of 0 is allowed.
  171.       string dup () ne { 1 index exec } if
  172.     } {
  173.       mark 3 1 roll {
  174.         % Stack: mark str ... readproc length
  175.     dup 0 eq { pop exit } if
  176.     dup 65400 .min dup string 3 index exec
  177.         % Stack: mark str ... readproc length newstrlen newstr
  178.     4 1 roll sub
  179.       } loop
  180.       counttomark 1 add 1 roll ]
  181.     } ifelse
  182.     /GlyphData exch def
  183.         % If we were reading hex data, skip past the >.
  184.     2 get { readhexstring } 0 get eq {
  185.       currentfile 0 (>) .subfiledecode dup flushfile closefile
  186.     } if
  187.   } {
  188.         % File is positionable and binary, just save a pointer.
  189.         % Stack: (Binary) length -mark- pos
  190.     /GlyphData 0 def
  191.     exch pop 3 -1 roll pop exch
  192.         % Stack: pos length
  193.     /DataSource currentfile 2 index () .subfiledecode true .reusablestream def
  194.     currentfile 3 1 roll add setfileposition
  195.   } ifelse
  196.   /SubrCache 10 dict def
  197.   CIDFontName currentdict /CIDFont defineresource pop
  198.   end            % CID font dict
  199.   end            % resource category dict
  200. } bind def
  201.  
  202. % Some Adobe fonts include the line
  203. %   /Setup /cid_Setup load def
  204. % This is apparently included only to prevent proper, conforming PostScript
  205. % interpreters (as opposed to ATM or a special Adobe font loader) from
  206. % loading the font, since Setup is not referenced anywhere else in the file.
  207. /cid_Setup { } def
  208.  
  209. currentdict end
  210.  
  211. % ---------------- Rendering ---------------- %
  212.  
  213. % ------ Generic ------ %
  214.  
  215. % Read a string at a given offset in a "file" (binary file or
  216. % GlyphData in RAM).
  217. /ReadString {        % <pos> <string> ReadString <string>
  218.   GlyphData 0 eq {
  219.     % Read from the file.
  220.     DataSource 3 -1 roll setfileposition
  221.     DataSource exch readstring pop
  222.   } {
  223.     % Read from a string or an array of strings.
  224.     GlyphData .stringsreadstring
  225.   } ifelse
  226. } bind def
  227. /.stringsreadstring    % <pos> <string> <strings> .stringsreadstring
  228.             %   <vmstring>
  229. { dup type /stringtype eq
  230.    { 3 1 roll length getinterval
  231.    }
  232.    {  {        % Stack: pos string glyphdata
  233.     dup 0 get length dup 4 index gt { exit } if
  234.     4 -1 roll exch sub 3 1 roll
  235.     dup length 1 sub 1 exch getinterval
  236.       }
  237.      loop
  238.         % Stack: pos string glyphdata glyphdata[0]length
  239.         % We know no request can span more than 2 strings.
  240.      3 index 3 index length add 1 index le
  241.       {        % Request fits in a single string: just return a substring.
  242.     pop 0 get 3 1 roll length getinterval
  243.       }
  244.       {        % Request spans 2 strings.  Copy the first part.
  245.     1 index 0 get 4 index 3 -1 roll 1 index sub getinterval
  246.     2 index copy
  247.         % Copy the second part.
  248.         % Stack: pos str glyphdata str1
  249.     length exch 1 get 0 3 index length
  250.     3 index sub getinterval 2 index 3 1 roll putinterval
  251.     exch pop
  252.       }
  253.      ifelse
  254.    }
  255.   ifelse
  256. } bind def
  257.  
  258. % Interpret a byte string as a (big-endian) integer.
  259. /.cvbsi            % <bytes> .cvbsi <int>
  260. { 0 exch { exch 8 bitshift add } forall
  261. } bind def
  262.  
  263. % Read an integer from binary data.
  264. /.readint        % <pos> <nbytes> .readint <int>
  265. { string ReadString .cvbsi
  266. } bind def
  267.  
  268. % ------ CIDFontType 0 ------ %
  269.  
  270. /.readglyphdata {
  271.   currentfont exch .type9mapcid
  272.   FDArray exch get exch
  273. } bind def
  274.  
  275. % BuildGlyph procedure for CIDFontType 0.
  276. % The name %Type9BuildGlyph is known to the interpreter.
  277. /.cid0buildstring 10 string def
  278. (%Type9BuildGlyph) cvn {    % <cidfont> <cid> %Type9BuildGlyph -
  279.   .currentglobal 3 1 roll 1 index gcheck .setglobal
  280.   1 index begin
  281.   dup .readglyphdata dup null eq {
  282.         % Substitute CID 0. **** WRONG ****
  283.     pop pop 0 .readglyphdata
  284.   } if
  285.         % Stack: cidfont cid subfont charstring
  286.   dup null eq { pop pop pop pop } {    %**** WRONG ****
  287.     4 -1 roll pop
  288.     3 1 roll exch dup 4 -1 roll 0 0 moveto
  289.     3 index /FontType get 2 eq { .type2execchar } { .type1execchar } ifelse
  290.   } ifelse    %**** WRONG ****
  291.   end
  292.   .setglobal
  293. } bind def
  294.  
  295. % ------ CIDFontType 2 ------ %
  296.  
  297. % BuildGlyph procedure for CIDFontType 2.
  298. % The name %Type11BuildGlyph is known to the interpreter.
  299. (%Type11BuildGlyph) cvn {    % <cidfont> <cid> %Type11BuildGlyph -
  300.         % We must be prepared for out-of-range CIDs.
  301.   2 copy { .type11mapcid } .internalstopped {
  302.     pop /CharStrings get /.notdef get
  303.   } if
  304.             % Stack: cidfont cid glyphindex
  305.   1 index exch .type42execchar
  306. } bind def
  307.  
  308. % ---------------- Define resources ---------------- %
  309.  
  310. languagelevel exch 2 .setlanguagelevel
  311.  
  312. % Define the CIDInit ProcSet resource.
  313. % The ProcSet dictionary is still on the stack.
  314.  
  315. % We might have loaded CMap support already.  However, Adobe's
  316. % protected font downloader defines a CIDInit ProcSet that will be
  317. % loaded from the filesystem later, so we must check specifically
  318. % for the ProcSet being defined in VM.
  319. /CIDInit /ProcSet 2 copy resourcestatus { pop 0 eq } { false } ifelse {
  320.   pop pop findresource dup length 4 index length add dict .copydict
  321.   4 -1 roll exch .copydict
  322. } {
  323.   3 -1 roll
  324. } ifelse exch defineresource pop
  325.  
  326. % Define the CIDFont resource category.
  327. % We break out .buildcidfont because it appears that at least for
  328. % Type 32 (CIDFontType 4) fonts, the font can be registered in the Font
  329. % category with only a CIDFontType and no FontType.
  330. /.buildcidfont {        % <name> <fontdict> .buildcidfont
  331.                 %   <name> <cidfont>
  332.   dup /CIDFontType get //.cidfonttypes exch get exec
  333. } odef
  334.  
  335. /.loadcidfontwithoutpop {
  336.     dup 4 string .peekstring pop dup (ttcf) eq exch (\000\001\000\000) eq or {
  337.     .loadcjkvttcidfont
  338.   } {
  339.     /CIDFont /Category findresource /.Instances get
  340.     dup length 2 div cvi dict .copydict exch
  341.     .loadfont
  342.     % Stack: <<original-.Instances>>
  343.     /CIDFont /Category findresource /.Instances get {% forall
  344.     % <<original-.Instances>> key value
  345.     2 index 2 index known {
  346.         pop pop
  347.     } {
  348.         pop exch pop /CIDFont findresource exit
  349.     } ifelse
  350.     } forall
  351.     dup /CIDFontName known not {
  352.     {Internal Error in .loadcidfontwithoutpop} stop
  353.     } if
  354.   } ifelse
  355. } bind def
  356.  
  357. /.loadcidfont {
  358.   .loadcidfontwithoutpop pop
  359. } bind def
  360.  
  361. % Define the name of the CID font map file.
  362. /defaultcidfontmap (CIDFnmap) def
  363. userdict /CIDFontmap 10 dict put
  364.  
  365. % <dict> <file> .readCIDFontmap <dict>
  366. % Code from gs_fonts.ps::.readFontmap
  367. /.readCIDFontmap {
  368.     { dup token not { closefile exit } if
  369.       % This is a hack to get around the absurd habit of MS-DOS editors
  370.       % of adding an EOF character at the end of the file.
  371.       dup (\032) eq { pop closefile exit } if
  372.       1 index token not
  373.        { (CIDFontmap entry for ) print dup =only
  374.      ( has no associated file or alias name!  Giving up.) = flush
  375.      {.readCIDFontmap} 0 get 1 .quit
  376.        } if
  377.       dup type dup /stringtype eq exch /nametype eq or not
  378.        { (CIDFontmap entry for ) print 1 index =only
  379.      ( has an invalid file or alias name!  Giving up.) = flush
  380.      {.readCIDFontmap} 0 get 1 .quit
  381.        } if
  382.         % stack: dict file cidfontname filename|aliasname
  383.       1 index type /stringtype eq
  384.       1 index type /nametype eq and 1 index xcheck and
  385.       1 index /run eq 2 index /.runlibfile eq or and {
  386.         % This is an inclusion entry.
  387.     pop findlibfile { exch pop } { file } ifelse
  388.     2 index exch .readCIDFontmap pop
  389.       } {
  390.         % This is a real entry.
  391.         % stack: dict file cidfontname filename|aliasname
  392.  
  393.         % Before staring a game, we need a hack.
  394.         % Some CJK pdf file contains a cidfontname that cannot 
  395.         % be represented as a nametype literal. Instead, the
  396.         % cidfontname is represented as a string literal.
  397.         % If a cidfontname is represented as a stringtype object,
  398.         % it must be converted to a nametype object. 
  399.         % We handle such a case here.
  400.     exch dup type /stringtype eq {cvn} if exch
  401.  
  402.             % stack: dict file cidfontname filename|aliasname
  403.         % Read and pop tokens until a semicolon.
  404.        { 2 index token not
  405.       { (CIDFontmap entry for ) print 1 index =only
  406.         ( ends prematurely!  Giving up.) = flush
  407.         {.readCIDFontmap} 0 get 1 .quit
  408.       } if
  409.      dup /; eq { pop 3 index 3 1 roll .growput exit } if
  410.      % Format:
  411.      %   /CIDFontname (file) ttc-index ;
  412.      %   /CIDFontname (file) /Code->CID-dict ;
  413.      %   /CIDFontname (file) ttc-index /Code->CID-dict ;
  414.      %
  415.      % e.g.
  416.      %   /HG-MinchoL     (hgminchol.ttc) 1 /Adobe-Japan1-Unicode ;
  417.      %   /HG-PMinchoL    (hgminchol.ttc) 2 /Adobe-Japan1-Unicode ;
  418.      %   /HG-MinchoL-J2  (hgminchol.ttc) 1 /Adobe-Japan2-Unicode ;
  419.      %   /HG-PGothicB    (hggothicb.ttc) 2 ;
  420.      %   /HG-GothicB-J2  (hggothicb.ttc) /Adobe-Japan2-Unicode ;
  421.      % 
  422.      % CID Fontmap entry is stored into CIDFontmap dict as an array.
  423.      % Array format:
  424.      %   [filename ttc-index]
  425.      %   [filename /Code->CID-dict]
  426.      %   [filename ttc-index /Code->CID-dict]
  427.      %
  428.      % Type: 
  429.      %   filename: string
  430.      %   ttc-index: integer
  431.      %   /Code->CID-dict: name
  432.      %
  433.      % stack: dict file cidfontname filename something
  434.      1 index type /nametype eq {
  435.        (CIDFontmap entry for ) print 2 index =only
  436.        (defines an alias! Giving up.) = flush
  437.        {.readCIDFontmap} 0 get 1 .quit
  438.      } if
  439.      % stack: dict file cidfontname filename something
  440.      exch [ exch 3 -1 roll
  441.      % stack: dict file cidfontname [ filename something 
  442.      dup type /integertype eq {
  443.        % stack: dict file cidfontname [ filename int
  444.        % Read next token
  445.        4 index token not
  446.        { (CIDFontmap entry for ) print 3 index =only
  447.          ( ends prematurely!  Giving up.) = flush
  448.          {.readCIDFontmap} 0 get 1 .quit
  449.        } if
  450.      } if
  451.      % stack: dict file cidfontname [ filename int something
  452.      % or     dict file cidfontname [ filename something
  453.      dup /; eq not 1 index type /nametype eq and {
  454.        % stack: dict file cidfontname [ filename  /Code->CID
  455.        % or     dict file cidfontname [ filename  int /Code->CID
  456.        % Read next token
  457.        counttomark 2 eq {4} {5} ifelse index token not
  458.        { (CIDFontmap entry for ) print
  459.          counttomark 2 eq {3} {4} ifelse index =only
  460.          ( ends prematurely!  Giving up.) = flush
  461.          {.readCIDFontmap} 0 get 1 .quit
  462.        } if
  463.      } if
  464.      % stack: dict file cidfontname [ filename int /Code->CID something
  465.      % or     dict file cidfontname [ filename /Code->CID something
  466.      dup /; eq {
  467.          pop ]
  468.          3 index 3 1 roll .growput exit
  469.      } if
  470.      pop
  471.        } loop
  472.       } ifelse
  473.     } loop
  474. } bind def
  475.  
  476. % <file> .loadCIDFontmap -
  477. /.loadCIDFontmap {
  478.     userdict /CIDFontmap get exch
  479.     .readCIDFontmap pop
  480. } bind def
  481.  
  482. % Code from .loadinitialfonts
  483. /.loadinitialcidfonts
  484.  { NOCIDFONTMAP not
  485.     { /CIDFONTMAP where
  486.       { pop [ CIDFONTMAP .pathlist ]
  487.          {
  488.                dup VMDEBUG findlibfile
  489.         { exch pop .loadCIDFontmap }
  490.         { /undefinedfilename signalerror }
  491.            ifelse
  492.          }
  493.       }
  494.       { LIBPATH
  495.          {
  496.                defaultcidfontmap 1 index .filenamedirseparator
  497.            exch concatstrings concatstrings dup VMDEBUG
  498.            (r) { file } .internalstopped
  499.         { pop pop } { .loadCIDFontmap } ifelse
  500.          }
  501.       }
  502.      ifelse forall
  503.     }
  504.    if
  505.    %%% Do nothing
  506.  } bind def
  507.  
  508. .loadinitialcidfonts
  509.  
  510. /CIDFontmapHandler <<
  511.   /nametype {
  512.     /CIDFont findresource
  513.     /CIDFont defineresource pop
  514.   } bind
  515.   /stringtype {
  516.     findlibfile {
  517.       exch pop
  518.       % Define CIDFont with a name defined in the font file
  519.       .loadcidfontwithoutpop
  520.       % Define CIDFont with a name define in CIDFontmap
  521.       dup length 0 ne {
  522.       dup /CIDFontName get 2 index eq {
  523.           % Avoid duplicated defineresource for the same CIDFont
  524.           pop pop
  525.       } {
  526.           % Give a name different from the name defined in the file
  527.           /CIDFont defineresource pop
  528.       } ifelse
  529.       } {
  530.       pop pop
  531.       } ifelse
  532.     } {
  533.       /undefinedresource signalerror
  534.     } ifelse
  535.   } bind
  536.   /arraytype {
  537.   % Replace filename in the array with file
  538.       dup 0 get
  539.       findlibfile {
  540.       3 1 roll pop
  541.       copyarray dup 3 1 roll 0
  542.       3 -1 roll put
  543.       % Expand array
  544.       aload pop .loadcjkvttcidfont
  545.       /CIDFont defineresource pop
  546.       } {
  547.       /undefinedresource signalerror
  548.       } ifelse
  549.   } bind
  550. >> def
  551.  
  552. %%% CIDFontmap Public Interface
  553. % /CIDFontName .CIDFontmapKnown true|false
  554. /.CIDFontmapKnown {
  555.     userdict /CIDFontmap get exch known
  556. } bind def
  557.  
  558. % /CIDFontName .CIDFontmapKnownget value true
  559. % /CIDFontName .CIDFontmapKnownget false
  560. /.CIDFontmapKnownget {
  561.     userdict /CIDFontmap get exch .knownget
  562. } bind def
  563.  
  564. % /CIDFontName value .CIDFontmapRunHandler -
  565. /.CIDFontmapRunHandler {
  566.     dup CIDFontmapHandler exch type get .execasresource
  567. } bind def
  568.  
  569. % proc .CIDFontmapForAll -
  570. /.CIDFontmapForAll {
  571.     CIDFontmap exch forall
  572. } bind def
  573.  
  574. % proc .CIDFontmapForAllKey -
  575. /.CIDFontmapForAllKey {
  576.     [ /pop cvx 3 -1 roll /exec cvx ] cvx .CIDFontmapForAll
  577. } bind def
  578.  
  579. /CIDFont /Generic /Category findresource dup length dict .copydict
  580. dup /InstanceType /dicttype put
  581. dup /DefineResource {
  582.   .buildcidfont
  583.   /Generic /Category findresource /DefineResource get exec
  584. } put
  585. /.originalresourceforall 1 index /ResourceForAll get def
  586. dup /ResourceForAll {
  587.     currentglobal false setglobal
  588.     % (template) (proc) (scratch) g
  589.     [           % (template) (proc) (scratch) g [
  590.     %
  591.     % 1. Gather CIDFont name in /Resource/CIDFont
  592.     %
  593.     4 index % (template) (proc) (scratch) g [ (template)
  594.     {cvn}      % (template) (proc) (scratch) g [ (template) {cvn}
  595.     4 index % (template) (proc) (scratch) g    [ (template) {cvn} (scratch)
  596.     .originalresourceforall
  597.     % (template) (proc) (scratch) g [ ...
  598.     %
  599.     % 2. Gather CIDFont name in CIDFontmap
  600.     %
  601.     {
  602.         dup length string cvs
  603.         dup     % (template) (proc) (scratch) g [ ... (Key) (Key)
  604.         counttomark 4 add index
  605.         % (template) (proc) (scratch) g [ ... (Key) (Key) (template)
  606.         .stringmatch {
  607.         cvn
  608.         % (template) (proc) (scratch) g [ ... /Key
  609.         % 3. Remove duplicated /Key
  610.         counttomark -1 1  {
  611.             index 1 index eq {
  612.             pop exit % Duplicated
  613.             } if
  614.         } for
  615.         } {
  616.         pop
  617.         } ifelse
  618.     } .CIDFontmapForAllKey
  619.     ]
  620.     exch setglobal
  621.     %
  622.     % 4. Build extended procedure
  623.     %
  624.     % (template) (proc) (scratch) [CIDFontmapKeys]
  625.     4 -1 roll pop
  626.     % (proc) (scratch) [CIDFontmapKeys]
  627.     3 1 roll
  628.     % [CIDFontmapKeys] (proc) (scratch)
  629.     [ exch {cvs} aload pop
  630.     % [CIDFontmapKeys] (proc) [ (scratch) -cvs-
  631.     4 -1 roll aload pop ] cvx
  632.     % [CIDFontmapKeys] proc++
  633.     %
  634.     % 5. Exec
  635.     %
  636.     forall
  637. } put
  638.  
  639. % CIDFonts may be defined in CFF OpenType files.
  640. % Check for this here.
  641. /.loadcidfontresource {
  642.   dup .ResourceFile {
  643.     {.loadcidfont} .execasresource
  644.   } {
  645.     pop dup
  646.     .CIDFontmapKnownget {
  647.       .CIDFontmapRunHandler
  648.     } {
  649.       dup /undefinedresource signalerror
  650.     } ifelse
  651.   } ifelse
  652. } bind def
  653. dup /.LoadResource {
  654.   currentglobal {
  655.     .loadcidfontresource
  656.   } {
  657.     true setglobal {.loadcidfontresource} stopped false setglobal {stop} if
  658.   } ifelse
  659. } bind put
  660. dup /.ResourceFileStatus {
  661.     dup .CIDFontmapKnown {
  662.     pop 2 -1 true
  663.   } {
  664.     .ResourceFile { closefile 2 -1 true } { pop false } ifelse
  665.   } ifelse
  666. } bind put
  667.  
  668. /Category defineresource pop
  669.  
  670. % Add the new FontType resources.
  671.  
  672. 9 1 11 { dup /FontType defineresource pop } for
  673.  
  674. % Add the new FMapType resource.
  675.  
  676. 9 dup /FMapType defineresource pop
  677.  
  678. % Define the CIDMap resource category.
  679. % These aren't documented, but it's clear what they are for:
  680. % to give names to CIDMaps for CIDFontType 2 fonts.
  681.  
  682. /CIDMap /Generic /Category findresource dup length dict .copydict
  683. dup /.CheckResource {
  684.     % Allow a string, an array of strings, or (as of Adobe release 3011)
  685.     % a dictionary.
  686.   dup type dup dup /stringtype eq exch /dicttype eq or {
  687.     pop true
  688.   } {
  689.     dup /arraytype eq exch /packedarraytype eq or {
  690.       true exch { type /stringtype eq and } forall
  691.     } {
  692.       false
  693.     } ifelse
  694.   } ifelse
  695. } bind put
  696. /Category defineresource pop
  697.  
  698. .setlanguagelevel
  699.